package com.heima.safe.aliyun.verify;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;

import com.aliyuncs.green.model.v20180509.ImageSyncScanRequest;
import com.aliyuncs.http.FormatType;
import com.aliyuncs.http.HttpResponse;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.http.ProtocolType;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import com.heima.dfs.api.UploadFeign;
import com.heima.safe.aliyun.util.ClientUploader;
import lombok.Data;
import org.apache.commons.io.FileUtils;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import java.io.File;
import java.util.*;

@Data
@Component
@ConfigurationProperties(prefix = "aliyun")
public class VerifyImage {

    /**
     * AccessKey ID:        LTAI5tLr1CvwGqKzmLSdc1sa
     * AccessKey Secret:    A5nBlAY44xyjPIDGuXyRc6tU5Ea7hU
     *
     * @throws Exception
     */

    private String accessKeyId;// LTAI5tLr1CvwGqKzmLSdc1sa

    private String secret;// A5nBlAY44xyjPIDGuXyRc6tU5Ea7hU

    private String regionId;// cn-shanghai

    private String verifyText;// antispam

    private String[] verifyImage;// orc,porn,terrorism,ad,qrcode,live,logo


    @Autowired
    private UploadFeign uploadFeign;

    /**
     * @param urls：图片地址
     * @return
     */
    public Map<String, String> verify(List<String> urls) throws Exception {

        IClientProfile profile = DefaultProfile
                .getProfile(regionId, accessKeyId, secret);
        DefaultProfile
                .addEndpoint(regionId, "Green", "green.cn-shanghai.aliyuncs.com");
        IAcsClient client = new DefaultAcsClient(profile);

        ImageSyncScanRequest imageSyncScanRequest = new ImageSyncScanRequest();
        // 指定返回格式。
        imageSyncScanRequest.setAcceptFormat(FormatType.JSON);
        // 指定请求方法。
        imageSyncScanRequest.setMethod(MethodType.POST);
        imageSyncScanRequest.setEncoding("utf-8");
        // 支持HTTP和HTTPS。
        imageSyncScanRequest.setProtocol(ProtocolType.HTTP);

        JSONObject httpBody = new JSONObject();
        /**
         * 设置要检测的场景。
         * ocr：表示OCR图文识别和OCR卡证识别。
         */
        httpBody.put("scenes", Arrays.asList(verifyImage));
        /**
         * 设置待检测的图片，一张图片对应一个检测任务。
         * 多张图片同时检测时，处理时间由最后一张处理完的图片决定。
         * 通常情况下批量检测的平均响应时间比单任务检测长，一次批量提交的图片数越多，响应时间被拉长的概率越高。
         * 代码中以单张图片检测作为示例，如果需要批量检测多张图片，请自行构建多个任务。
         * 图片二进制数据检测相对于互联网图片链接，多了一个上传步骤，上传后取返回的链接进行检测。
         */
        ClientUploader clientUploader = ClientUploader.getImageClientUploader(profile, false);
        //===========================1个图片1个task，多个图片多个task===========================

        List<JSONObject> tasks = new ArrayList<>();//构建一个tasks的集合

        //1.到fastdfs上下载 urls所有图片，获取所有图片的字节数组
        List<byte[]> allImagesBytes = uploadFeign.download(urls);
        //2.循环每个图片，在每个图片下创建task
        for (byte[] imagesByte : allImagesBytes) {
            String url = null;
            try {
                // 上传到服务端阿里云。
            url = clientUploader.uploadBytes(imagesByte);
            } catch (Exception e) {
                System.out.println("upload file to server fail.");
            }

            JSONObject task = new JSONObject();
            task.put("dataId", UUID.randomUUID().toString());
            task.put("url", url);
            task.put("time", new Date());

            tasks.add(task);
        }

        httpBody.put("tasks", Arrays.asList(tasks));


        /**
         * 请设置超时时间。服务端全链路处理超时时间为10秒，请据此做相应设置。
         * 如果您设置的ReadTimeout小于服务端处理的时间，程序中会获得一个read timeout异常。
         */
        imageSyncScanRequest.setConnectTimeout(3000);
        imageSyncScanRequest.setReadTimeout(10000);
        HttpResponse httpResponse = null;
        try {
            httpResponse = client.doAction(imageSyncScanRequest);
        } catch (Exception e) {
            e.printStackTrace();
        }
        // 服务端接收到请求，并完成处理返回的结果。
        if (httpResponse != null && httpResponse.isSuccess()) {
            JSONObject scrResponse = JSON.parseObject(org.apache.commons.codec.binary.StringUtils.newStringUtf8(httpResponse.getHttpContent()));
            System.out.println(JSON.toJSONString(scrResponse));
            int requestCode = scrResponse.getIntValue("code");
            // 每一张图片的检测结果。
            JSONArray taskResults = scrResponse.getJSONArray("data");
            if (200 == requestCode) {
                //保存检测结果
                HashMap<String, String> resultMap = new HashMap<>();


                for (Object taskResult : taskResults) {
                    // 单张图片的处理结果。
                    int taskCode = ((JSONObject) taskResult).getIntValue("code");
                    // 对应检测场景下，图片的处理结果。如果是多个场景，则会有每个场景的结果。
                    JSONArray sceneResults = ((JSONObject) taskResult).getJSONArray("results");
                    if (200 == taskCode) {
                        for (Object sceneResult : sceneResults) {
                            String scene = ((JSONObject) sceneResult).getString("scene");
                            String suggestion = ((JSONObject) sceneResult).getString("suggestion");
                            //根据scene和suggestion做相关处理
                            //根据不同的suggestion结果做业务上的不同处理。例如，将违规数据删除等。
                            resultMap.put("scene",scene);
                            resultMap.put("suggestion",suggestion);


                            // 识别出来的卡证信息。
                            if ("review".equals(suggestion) && "ocr".equals(scene)) {
                                JSONObject idCardInfo = ((JSONObject) sceneResult).getJSONObject("idCardInfo");
                                System.out.println(idCardInfo.toJSONString());
                            }
                        }
                    } else {
                        // 单张图片处理失败，原因视具体的情况详细分析。
                        System.out.println("task process fail. task response:" + JSON.toJSONString(taskResult));
                    }
                }
                return resultMap;
            } else {
                /**
                 * 表明请求整体处理失败，原因视具体的情况详细分析。
                 */
                System.out.println("the whole image scan request failed. response:" + JSON.toJSONString(scrResponse));
            }
        }
        return null;
    }

}

